//
//  CNString.swift
//  Voice
//
//  Created by 卢逢卫 on 2024/3/8.
//

import UIKit
import CommonCrypto

extension String {
    public var cn_nibPath: String? {
        // Implementation goes here
        return nil
    }
    
    public var cn_createNib: UINib? {
        // Implementation goes here
        return nil
    }
    
    public static func cn_allStringHaveValue(strArr: [String?]) -> Bool {
        // Implementation goes here
        return strArr.allSatisfy { $0 != nil && !$0!.isEmpty }
    }
    
    public static func cn_strArrContainGivenValue(compare: String?, strArr: [String?]) -> Bool {
        // Implementation goes here
        return strArr.contains { $0 == compare }
    }
    
    public var cn_intValue: Int {
        // Implementation goes here
        return Int(self) ?? 0
    }
    
    public var cn_doubleValue: Double {
        // Implementation goes here
        return Double(self) ?? 0.0
    }
    
    public var cn_floatValue: Float {
        // Implementation goes here
        return Float(self) ?? 0.0
    }
    
    public var cn_dataValue: Data {
        // Implementation goes here
        return Data(self.utf8)
    }
    
    public var cn_urlEscapedString: String {
        // Implementation goes here
        return self.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? ""
    }
    
    public var length: Int {
        // Implementation goes here
        return self.count
    }
    
    public subscript(i: Int) -> String {
        // Implementation goes here
        guard i >= 0 && i < self.count else { return "" }
        return String(self[index(startIndex, offsetBy: i)])
    }
    
    public func substring(fromIndex: Int) -> String {
        // Implementation goes here
        guard fromIndex >= 0 && fromIndex < self.count else { return "" }
        let startIndex = index(self.startIndex, offsetBy: fromIndex)
        return String(self[startIndex...])
    }
    
    public func substring(toIndex: Int) -> String {
        // Implementation goes here
        guard toIndex >= 0 && toIndex <= self.count else { return "" }
        let endIndex = index(self.startIndex, offsetBy: toIndex)
        return String(self[..<endIndex])
    }
    
    public subscript(r: Range<Int>) -> String {
        // Implementation goes here
        let startIndex = index(self.startIndex, offsetBy: r.lowerBound)
        let endIndex = index(self.startIndex, offsetBy: r.upperBound)
        return String(self[startIndex..<endIndex])
    }
    
    public static func cn_getFirstLetter(strInput: String?) -> String {
        // Implementation goes here
        guard let str = strInput else { return "" }
        guard let firstChar = str.first else { return "" }
        return String(firstChar)
    }
    
    public func cn_getStringWidth(byHeight height: CGFloat, font: UIFont) -> CGFloat {
        // Implementation goes here
        let attributes: [NSAttributedString.Key: Any] = [.font: font]
        let size = CGSize(width: CGFloat.greatestFiniteMagnitude, height: height)
        let boundingRect = self.boundingRect(with: size, options: .usesLineFragmentOrigin, attributes: attributes, context: nil)
        return boundingRect.width
    }
    
    public func cn_getStringHeight(byWidth width: CGFloat, font: UIFont) -> CGFloat {
        // Implementation goes here
        let attributes: [NSAttributedString.Key: Any] = [.font: font]
        let size = CGSize(width: width, height: CGFloat.greatestFiniteMagnitude)
        let boundingRect = self.boundingRect(with: size, options: .usesLineFragmentOrigin, attributes: attributes, context: nil)
        return boundingRect.height
    }
    
    public func cn_getStringSize(bySize size: CGSize, font: UIFont) -> CGSize {
        // Implementation goes here
        let attributes: [NSAttributedString.Key: Any] = [.font: font]
        let boundingRect = self.boundingRect(with: size, options: .usesLineFragmentOrigin, attributes: attributes, context: nil)
        return CGSize(width: boundingRect.width, height: boundingRect.height)
    }
}


extension String {

    public func cn_md5() -> String {
        let data = self.data(using: .utf8)!
        var digest = [UInt8](repeating: 0, count: Int(CC_MD5_DIGEST_LENGTH))
        _ = data.withUnsafeBytes { (bytes) in
            CC_MD5(bytes.baseAddress, CC_LONG(data.count), &digest)
        }
        var md5String = ""
        for byte in digest {
            md5String += String(format: "%02x", byte)
        }
        return md5String
    }

    public func cn_SHA256() -> String {
        let data = self.data(using: .utf8)!
        var digest = [UInt8](repeating: 0, count: Int(CC_SHA256_DIGEST_LENGTH))
        _ = data.withUnsafeBytes { (bytes) in
            CC_SHA256(bytes.baseAddress, CC_LONG(data.count), &digest)
        }
        var sha256String = ""
        for byte in digest {
            sha256String += String(format: "%02x", byte)
        }
        return sha256String
    }
}

//extension String {
//    func cn_setAttributedString(colors: [UIColor], fonts: [UIFont], texts: [String]) -> NSAttributedString {
//        let attributedString = NSMutableAttributedString(string: self)
//        
//        guard colors.count == fonts.count && colors.count == texts.count else {
//            return attributedString
//        }
//        
//        var index = 0
//        for (color, font, text) in zip(colors, fonts, texts) {
//            let range = (self as NSString).range(of: text)
//            
//            attributedString.addAttribute(.foregroundColor, value: color, range: range)
//            attributedString.addAttribute(.font, value: font, range: range)
//            
//            index += 1
//        }
//        
//        return attributedString
//    }
//}


//extension String {
//    func cn_setAttributedString(colors: [UIColor], fonts: [UIFont], texts: [String]) -> NSAttributedString {
//        let attributedString = NSMutableAttributedString(string: self)
//        
//        guard colors.count == fonts.count && colors.count == texts.count else {
//            return attributedString
//        }
//        
//        var index = 0
//        for (color, font, text) in zip(colors, fonts, texts) {
//            let range = (self as NSString).range(of: text)
//            
//            attributedString.addAttribute(.foregroundColor, value: color, range: range)
//            attributedString.addAttribute(.font, value: font, range: range)
//            
//            index += 1
//        }
//        
//        return attributedString
//    }
//}

extension String {
    static func cn_setAttributedString(colors: [UIColor], fonts: [UIFont], texts: [String]) -> NSAttributedString {
            let att = NSMutableAttributedString()

            for i in 0..<colors.count {
                let color = colors[i]
                let font = fonts[i]
                let text = texts[i]
                
                let attributes: [NSAttributedString.Key: Any] = [
                    .foregroundColor: color,
                    .font: font
                ]
                
                let attributedString = NSAttributedString(string: text, attributes: attributes)
                att.append(attributedString)
            }
            
            return att
        }
}
